using System;
using System.IO;
using System.Collections.Generic;
using System.Text;

namespace LumiSoft.Net.MIME
{
    /// <summary>
    /// Represents MIME entity body. This is base class for all MIME bodies. Defined in RFC 2045 
    /// </summary>
    public abstract class MIME_Body : IDisposable
    {
        private bool        m_IsDisposed = false;
        private MIME_Entity m_pOwner     = null;

        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="owner">Owner MIME entity.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>owner</b> is null.</exception>
        internal MIME_Body(MIME_Entity owner)
        {
            if(owner == null){
                throw new ArgumentNullException("owner");
            }

            m_pOwner = owner;
        }

        #region method Dispose

        /// <summary>
        /// Cleans up any resources being used. This method is thread-safe.
        /// </summary>
        public virtual void Dispose()
        {
            lock(this){
                if(m_IsDisposed){
                    return;
                }
                m_IsDisposed = true;
            }
        }

        #endregion


        #region method ToFile

        /// <summary>
        /// Stores MIME entity body to the specified file.
        /// </summary>
        /// <param name="file">File name with path where to store MIME entity body.</param>
        /// <exception cref="ObjectDisposedException">Is raised when this object is disposed and this method is accessed.</exception>
        /// <exception cref="ArgumentNullException">Is raised when <b>file</b> is null.</exception>
        /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception>
        public void ToFile(string file)
        {
            if(m_IsDisposed){
                throw new ObjectDisposedException(this.GetType().Name);
            }
            if(file == null){
                throw new ArgumentNullException("file");
            }
            if(file == ""){
                throw new ArgumentException("Argument 'file' value must be specified.");
            }

            using(FileStream fs = File.Create(file)){
                ToStream(fs);
            }
        }

        #endregion

        #region abstract method ToStream

        /// <summary>
        /// Stores MIME entity body to the specified stream.
        /// </summary>
        /// <param name="stream">Stream where to store body. Storing starts from stream current position.</param>
        public abstract void ToStream(Stream stream);

        #endregion


        internal abstract bool ParseFromStream(Stream stream,bool owner);


        #region Properties Implementation

        /// <summary>
        /// Gets if this object is dispoed.
        /// </summary>
        public bool IsDisposed
        {
            get{ return m_IsDisposed; }
        }

        /// <summary>
        /// Gets owner MIME entity.
        /// </summary>
        /// <exception cref="ObjectDisposedException">Is raised when this object is disposed and this property is accessed.</exception>
        public MIME_Entity Owner
        {
            get{
                if(m_IsDisposed){
                    throw new ObjectDisposedException(this.GetType().Name);
                }

                return m_pOwner; 
            }
        }

        #endregion

    }
}
